#pragma once

#include <string>
#include <vector>
#include "DisholImage.h"
#include "DisholCaptureSettings.h"
#include "DisholCapturedImage.h"

namespace Dishol
{

class DeviceManager;
class DeviceInternals;	

/*
	Device

	Strings are UTF-8 encoded.
*/
class Device
{
public:
	DeviceManager*					getParentDeviceManager() const		{ return mParentDeviceManager; }
	const std::string&				getName() const						{ return mName; }
	const std::string&				getPath() const						{ return mPath; }
	const CaptureSettingsList&		getSupportedCaptureSettings() const	{ return mSupportedCaptureSettings; }

	bool							isCapturing() const;
	bool							startCapture( std::size_t captureSettingsIndex );
	bool							getStartedCaptureSettingsIndex( unsigned int& index ) const;
	const CapturedImage*			getCapturedImage() const			{ return mCapturedImage; }
	void							stopCapture();

	void							update();

	class Listener
	{
	public:
		virtual ~Listener() {}
		virtual void onDeviceStarted( Device* /*device*/ ) {}
		virtual void onDeviceCapturedImage( Device* /*device*/ ) {}
		virtual void onDeviceStopping( Device* /*device*/ ) {}
	};

	void							addListener( Listener* listener );
	bool							removeListener( Listener* listener );

protected:
	friend class DeviceManager;
	Device( DeviceManager* parentDeviceManager, void* monikerSharedPtrAsVoidPtr, const std::string& name, const std::string& path );
	virtual ~Device();

private:
	DeviceManager*					mParentDeviceManager;
	std::string						mName;
	std::string						mPath;

	CaptureSettingsList				mSupportedCaptureSettings;
	std::vector<std::size_t>		mMediaTypeIndices;			// For each CaptureSettings, contains the index of the corresponding MediaType

	DeviceInternals*				mInternals;
	
	unsigned int					mStartedCaptureSettingsIndex;
	CapturedImage*					mCapturedImage;
	
	typedef	std::vector<Listener*> Listeners; 
	Listeners						mListeners;
};

typedef std::vector<Device*> Devices;

}